package controls;

import java.util.ArrayList;

import util.IniParameters;

import model.TaskElement;
import model.Tasks;

public class ElevatorControl implements Refreshable {
	private int currentLevel = IniParameters.initialFloor;
	private Tasks taskUtility;
	private int topLevel = IniParameters.numberOfFloors - 1;
	private int direction = 0; // 1 for up, 0 for stable, -1 for down

	private boolean isLeft;

	public void refresh() {
		if (!check()) {
			updateWaitingTime();

			if (direction == 1 && currentLevel < topLevel) {
				currentLevel++;
			} else if (direction == 1 && currentLevel == topLevel) {
				direction = 0;
			} else if (direction == -1 && currentLevel > 0) {
				currentLevel--;
			} else if (direction == -1 && currentLevel == 0) {
				direction = 0;
			} else { // (direction == 0)
				return;
			}
		} else {
			updateWaitingTime();
		}
	}

	public ElevatorControl(Tasks tasks, boolean isLeft) {
		taskUtility = tasks;
		this.isLeft = isLeft;

		CenterTimer.getInstance().addToControlRefreshList(this);
	}

	public int getCurrentLevel() {
		return currentLevel;
	}

	// called for each level
	private boolean check() {
		// taskUtility.doingTask(currentLevel, direction);
		// taskUtility.finishTask(currentLevel);
		int currentDirection = direction;
		boolean isLoadingNeeded;
		boolean isUnloadingNeeded;

		if (direction == 1) {
			direction = taskUtility.UpMovingCheck(currentLevel);
		} else if (direction == -1) {
			direction = taskUtility.downMovingCheck(currentLevel);
		} else if (direction == 0) {
			direction = taskUtility.stableCheck(currentLevel);
		}

		//finishTask must be called prior to doingTask
		isUnloadingNeeded = taskUtility.finishTask(currentLevel);
		isLoadingNeeded = taskUtility.doingTask(currentLevel, direction);
		
		if (direction == 1) {
			direction = taskUtility.UpMovingCheck(currentLevel);
		} else if (direction == -1) {
			direction = taskUtility.downMovingCheck(currentLevel);
		} else if (direction == 0) {
			direction = taskUtility.stableCheck(currentLevel);
		}

		// solve the problem that the elevator cannot both load persons and
		// unload persons
		// when elevator changes direction
		if (direction != 0 && currentDirection != 0
				&& direction != currentDirection) {
			isLoadingNeeded = taskUtility.doingTask(currentLevel, direction);
		}

		return (isLoadingNeeded || isUnloadingNeeded);

	}

	private void updateWaitingTime() {
		ArrayList<TaskElement> elements;
		if (isLeft)
			elements = CenterTimer.getInstance().getLeftWaitingTaskElements();
		else
			elements = CenterTimer.getInstance().getRightWaitingTaskElements();

		if (elements != null) {
			for (TaskElement e : elements) {
				taskUtility.addToTotalWaitingTime(e.getCurrentWaitingTime());
			}
		}
	}
}
